﻿using CPPEI.Coolzon.Event.NCL;
using CPPEI.Coolzon.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Animation;
using System.Windows.Threading;

namespace Coolvis.Console.Theme.MainViewControl
{
    public partial class ZoomView
    {
        enum UIEventType
        {
            None,
            /// <summary>
            /// 鼠标触发
            /// </summary>
            Mouse,
            /// <summary>
            /// 触摸触发
            /// </summary>
            Touch,
        }

        enum UIEventState
        {
            None = 0,
            Down = 1,
            Up = 2,
            Leave = 3,
        }

        enum UIInteractiveType
        {
            None = 0,
            /// <summary>
            /// 移动区域
            /// </summary>
            MoveArea = 1,
            /// <summary>
            /// 移动摄像头
            /// </summary>
            MoveCamera = 2,
            /// <summary>
            /// 显示激光笔
            /// </summary>
            ShowLaserPoint = 3,
            /// <summary>
            /// 显示放大镜
            /// </summary>
            ShowMagnifier = 4,
        }

        private UIEventType _eventType = UIEventType.None;
        private UIEventState _eventState = UIEventState.None;
        private UIInteractiveType _interactiveType = UIInteractiveType.None;

        /// <summary>
        /// 事件发生所在的区域
        /// </summary>
        private WeakReference _downArea;

        private Storyboard _sbStoryboard;

        /// <summary>
        /// 监控interaction坐标的定时器
        /// </summary>
        private System.Timers.Timer _listenInteractionTimer;

        /// <summary>
        /// 上一次处理的点
        /// </summary>
        private Point _updatedPoint;
        /// <summary>
        /// 当前点
        /// </summary>
        private Point _currentPoint;

        /// <summary>
        /// 初始化
        /// 必须调用OnDestoryEvent在视图关闭的时候
        /// </summary>
        private void OnInitEvent()
        {
            _listenInteractionTimer = new System.Timers.Timer();
            _listenInteractionTimer.Interval = 200;
            _listenInteractionTimer.Elapsed += _listenInteractionTimer_Tick;
            _listenInteractionTimer.Start();
        }

        /// <summary>
        /// 
        /// </summary>
        private void OnDestoryEvent()
        {
            _listenInteractionTimer.Stop();
            _listenInteractionTimer = null;
        }

        void _listenInteractionTimer_Tick(object sender, EventArgs e)
        {
            if (_interactiveType == UIInteractiveType.MoveArea)
            {
            }
            else if (_interactiveType == UIInteractiveType.MoveCamera)
            {
            }
            else if (_interactiveType == UIInteractiveType.ShowMagnifier)
            {
                if (_currentPoint != _updatedPoint)
                {
                    _updatedPoint = _currentPoint;

                    NCLEventBus.PublishAsync(new NCLShowMagnifierEvent(true, _Scene.Name, 1.5d, _updatedPoint.X / _scaleX,
                        _updatedPoint.Y / _scaleY, 400, 0.1));
                }
            }
            else if (_interactiveType == UIInteractiveType.ShowLaserPoint)
            {
                if (_currentPoint != _updatedPoint)
                {
                    _updatedPoint = _currentPoint;

                    Point desPoint = new Point(_updatedPoint.X / _scaleX, _updatedPoint.Y / _scaleY);
                    NCLEventBus.PublishAsync(new NCLShowLaserPointerEvent(true, _Scene.Name, 0, desPoint.X, desPoint.Y, 10, 0.1));
                }
            }
        }

        private void ResetInteractivePoint()
        {
            _currentPoint = new Point(0, 0);
            _updatedPoint = new Point(0, 0);
        }

        #region storyboard
        private Storyboard CreateStoryboard()
        {
            Storyboard storyboard = new Storyboard();
            storyboard.FillBehavior = FillBehavior.Stop;
            DoubleAnimation doubleAnimation = new DoubleAnimation();
            doubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(500));
            doubleAnimation.From = 0;
            doubleAnimation.To = 70.0d;
            Storyboard.SetTargetName(doubleAnimation, "_ctlRectPrepare");
            Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(Rectangle.Width)"));

            storyboard.Children.Add(doubleAnimation);

            storyboard.Completed += storyboard_Completed;

            return storyboard;
        }

        void storyboard_Completed(object sender, EventArgs e)
        {
            ClockGroup clockGroup = sender as ClockGroup;
            if (clockGroup.CurrentState == ClockState.Stopped)
            {
                if (_sbStoryboard != null)
                {
                    System.Diagnostics.Debug.WriteLine("Finished");
                    _interactiveType = UIInteractiveType.MoveArea;

                    AreaPart downArea = _downArea.Target as AreaPart;
                    if (downArea != null)
                    {
                        CreateScaleView(downArea);
                    }

                    _sbStoryboard.Remove(this);
                    _sbStoryboard = null;
                    _ctlRectPrepareBorder.Visibility = System.Windows.Visibility.Hidden;
                }
            }
        }
        #endregion

        private void Down(Point point)
        {
            if (_interactiveType == UIInteractiveType.ShowLaserPoint
                || _interactiveType == UIInteractiveType.ShowMagnifier)
            {
                _currentPoint = point;
            }
            else
            {
                _oldPoint = PointToScreen(point);
                _downArea = new WeakReference(GetAreaPartAtPoint(point.X, point.Y));
                if (_Scene.IsAllowSwapArea)
                {
                    if (_sbStoryboard == null)
                    {
                        _sbStoryboard = CreateStoryboard();
                        _ctlRectPrepareBorder.Visibility = System.Windows.Visibility.Visible;
                        _sbStoryboard.Begin(this, true);
                    }
                }
                ScollToPos(point);
            }
        }

        private void Up(Point point)
        {
            _currentPoint = point;
            if (_sbStoryboard != null)
            {
                _sbStoryboard.Stop(this);
                _sbStoryboard.Remove(this);
                _sbStoryboard = null;
                _ctlRectPrepareBorder.Visibility = System.Windows.Visibility.Hidden;
            }

            if (_interactiveType == UIInteractiveType.MoveArea)
            {
                if (this._ctlRectDragMask.Tag != null)
                {
                    AreaPart target = GetAreaPartAtPoint(point.X, point.Y, 0);
                    AreaPart source = _ctlRectDragMask.Tag as AreaPart;
                    Swap(source, target);
                }
                CloseBorderWindow();
                _interactiveType = UIInteractiveType.None;
            }
            else if (_interactiveType == UIInteractiveType.MoveCamera)
            {
                _interactiveType = UIInteractiveType.None;
            }
        }

        private void Move(Point pos)
        {
            _currentPoint = pos;
            if (_interactiveType == UIInteractiveType.ShowLaserPoint)
            {
            }
            else if (_interactiveType == UIInteractiveType.ShowMagnifier)
            {
            }
            else if (_interactiveType == UIInteractiveType.MoveArea)
            {
                SetBorderWindowPoint();
                _oldPoint = pos;
            }
            else if (_interactiveType == UIInteractiveType.MoveCamera)
            {
                if (Math.Abs(pos.X - _mousePos.X) > _moveOffsetXY
                    || Math.Abs(pos.Y - _moveOffsetXY) > _moveOffsetXY)
                {
                    _mousePos = pos;
                    ScollToPos(pos);
                }
            }
            else
            {
                if (IsMouseMoving(_oldPoint, pos))
                {
                    if (_sbStoryboard != null)
                    {
                        _sbStoryboard.Stop(this);
                        _sbStoryboard.Remove(this);
                        _sbStoryboard = null;
                        _ctlRectPrepareBorder.Visibility = System.Windows.Visibility.Hidden;
                        _interactiveType = UIInteractiveType.MoveCamera;
                    }
                }
            }
        }

        private void ShowMagnifier(bool isEnable)
        {
            Point point = System.Windows.Input.Mouse.GetPosition(this);
            NCLEventBus.Publish(new NCLShowMagnifierEvent(isEnable, _Scene.Name, 1.5d, point.X / _scaleX,
                point.Y / _scaleY, 400, 0.1));
        }

        private void ShowPen(bool isShow)
        {
            Point point = System.Windows.Input.Mouse.GetPosition(this);
            Point desPoint = new Point(point.X / _scaleX, point.Y / _scaleY);
            NCLEventBus.Publish(
                new NCLShowLaserPointerEvent(isShow, _Scene.Name, 0, desPoint.X, desPoint.Y, 10, 0.1));
        }
    }
}
